import Utils, { Sync } from "../../core/utils";
import World from "./world";

const { requireComponent, ccclass, property } = cc._decorator;


@ccclass
@requireComponent(cc.Sprite)
export default class LightMap extends cc.Component {
    world: World = null;
    @property(cc.Camera)
    cam: cc.Camera = null;
    rt: cc.RenderTexture = null;
    _sprite: cc.Sprite = null;
    @property(cc.Sprite)
    get sprite() {
        if (!this._sprite) {
            this._sprite = this.getComponent(cc.Sprite);
            this._sprite.sizeMode = cc.Sprite.SizeMode.CUSTOM;
        }
        return this._sprite;
    }

    @property
    mapSizeAlignNode = false;
    @property({
        visible() {
            return !this.mapSizeAlignNode;
        },
    })
    mapSize = cc.size(0, 0);

    @property
    dynamic = false;

    protected onLoad(): void {
        if (this.mapSizeAlignNode) {
            this.mapSize = this.node.getContentSize();
        }
        this.cam.enabled = false;
        this.cam.alignWithScreen = true;
        this.cam.zoomRatio = Utils.game.node.height / this.node.height;

        this.rt = new cc.RenderTexture();
        this.rt.initWithSize(this.mapSize.width, this.mapSize.height, cc.RenderTexture.DepthStencilFormat.RB_FMT_D24S8);

        this.cam.targetTexture = this.rt;
        this.sprite.spriteFrame = new cc.SpriteFrame(this.rt);
        this.sprite.spriteFrame.setFlipY(true);

        this.sprite.getMaterial(0).setProperty("map_size", cc.v2(this.mapSize.width, this.mapSize.height));
    }

    setWorld(world: World) {
        this.world = world;

        Sync.NextUpdate().then(() => {
            if (cc.isValid(this)) {
                this.render();
            }
        });
    }

    render(world: World = null) {
        world = world || this.world;
        if (cc.isValid(world)) {
            world.bullets.forEach(bullet => {
                if (bullet.blockLight) {
                    bullet.node.groupIndex = this.cam.node.groupIndex;
                }
            });
            this.cam.render(world.node);

            world.bullets.forEach(bullet => {
                if (bullet.blockLight) {
                    bullet.node.groupIndex = world.node.groupIndex;
                }
            });
        }
    }

    protected update(dt: number): void {
        if (this.dynamic) {
            this.render();
        }
    }
};